import pygame
import time
import random
from settings import *
from background import Background
from hand import Hand
from hand_tracking import HandTracking
from mosquito import Mosquito
from bee import Bee
import cv2
import ui


class Game:
    def __init__(self, surface):
        self.surface = surface
        self.background = Background()
        self.cap = cv2.VideoCapture(0)
        self.frame = None  # 添加这一行初始化frame属性
        self.sounds = {}
        self.sounds["slap"] = pygame.mixer.Sound(f"assets/Sounds/slap.wav")
        self.sounds["screaming"] = pygame.mixer.Sound(f"assets/Sounds/screaming.wav")
        self.sounds["slap"].set_volume(SOUNDS_VOLUME)
        self.sounds["screaming"].set_volume(SOUNDS_VOLUME)
        self.reset()

    def load_camera(self):
        """从摄像头加载当前帧"""
        ret, self.frame = self.cap.read()
        if not ret:
            print("无法从摄像头读取帧")
            self.frame = None

    def reset(self):
        self.hand_tracking = HandTracking()
        self.hand = Hand(player=1)
        self.hand2 = Hand(player=2) if hasattr(self, 'is_two_player') and self.is_two_player else None
        self.insects = []
        self.insects_spawn_timer = 0
        self.scores = [0, 0]  # [player1, player2]
        self.game_start_time = time.time()
        self.time_left = GAME_DURATION

    def spawn_insects(self):
        t = time.time()
        if t > self.insects_spawn_timer:
            self.insects_spawn_timer = t + MOSQUITOS_SPAWN_TIME

            nb = (GAME_DURATION - self.time_left) / GAME_DURATION * 100 / 2
            if random.randint(0, 100) < nb:
                self.insects.append(Bee())
            else:
                self.insects.append(Mosquito())

            if self.time_left < GAME_DURATION / 2:
                self.insects.append(Mosquito())
                if self.hand2:  # In two player mode, spawn more insects
                    self.insects.append(Mosquito())

    def set_hand_positions(self):
        if self.hand2:  # Two player mode
            self.hand.rect.center = self.hand_tracking.get_hand_center("left")
            self.hand2.rect.center = self.hand_tracking.get_hand_center("right")
            self.hand.left_click = self.hand_tracking.is_hand_closed("left")
            self.hand2.left_click = self.hand_tracking.is_hand_closed("right")
        else:  # Single player mode
            self.hand.rect.center = self.hand_tracking.get_hand_center()
            self.hand.left_click = self.hand_tracking.is_hand_closed()

    def draw(self):
        self.background.draw(self.surface)
        for insect in self.insects:
            insect.draw(self.surface)
        self.hand.draw(self.surface)
        if self.hand2:
            self.hand2.draw(self.surface)

        # Draw scores
        ui.draw_text(self.surface, f"P1: {self.scores[0]}", (100, 5),
                     COLORS["score"], font=FONTS["medium"], shadow=True)
        if self.hand2:
            ui.draw_text(self.surface, f"P2: {self.scores[1]}", (SCREEN_WIDTH - 100, 5),
                         PLAYER_COLORS["player2"], font=FONTS["medium"], shadow=True)
        else:
            ui.draw_text(self.surface, f"Score: {self.scores[0]}", (SCREEN_WIDTH - 100, 5),
                         COLORS["score"], font=FONTS["medium"], shadow=True)

        # Draw timer
        timer_text_color = (160, 40, 0) if self.time_left < 5 else COLORS["timer"]
        ui.draw_text(self.surface, f"Time: {self.time_left}", (SCREEN_WIDTH // 2, 5),
                     timer_text_color, font=FONTS["medium"], shadow=True)

    def game_time_update(self):
        """更新游戏剩余时间（保留1位小数）"""
        self.time_left = max(round(GAME_DURATION - (time.time() - self.game_start_time), 1), 0)
    def update(self):
        self.load_camera()
        self.frame = self.hand_tracking.scan_hands(self.frame)
        self.set_hand_positions()
        self.game_time_update()
        self.draw()

        if self.time_left <= 0:
            result = self.show_game_over()
            if result:
                return result

        if self.time_left > 0:
            self.spawn_insects()

            # Update hand images based on click state
            for hand in [self.hand, self.hand2] if self.hand2 else [self.hand]:
                if hand and hand.left_click:
                    hand.image = hand.image_smaller.copy()
                else:
                    hand.image = hand.orig_image.copy()

            # Handle insect killing
            if self.hand.left_click:
                self.scores[0] += self.hand.kill_insects(self.insects, 0, self.sounds)
            if self.hand2 and self.hand2.left_click:
                self.scores[1] += self.hand2.kill_insects(self.insects, 0, self.sounds)

            for insect in self.insects:
                insect.move()
        else:
            if ui.button(self.surface, SCREEN_WIDTH // 2 - 100, "Continue", click_sound=self.sounds["slap"],
                         y_offset=0):
                return "menu"

        cv2.imshow("Frame", self.frame)
        cv2.waitKey(1)

    def show_game_over(self):
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 180))
        self.surface.blit(overlay, (0, 0))

        if self.hand2:
            winner = 1 if self.scores[0] > self.scores[1] else 2 if self.scores[1] > self.scores[0] else 0
            if winner == 0:
                text = "It's a Tie!"
                color = (255, 255, 255)
            else:
                text = f"Player {winner} Wins!"
                color = PLAYER_COLORS[f"player{winner}"]
        else:
            text = f"Final Score: {self.scores[0]}"
            color = COLORS["score"]

        ui.draw_text(self.surface, text, (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 - 50),
                     color, font=FONTS["medium"], shadow=True, center=True)

        if ui.button(self.surface, SCREEN_WIDTH // 2 - 100, "Play Again", y_offset=50):
            self.reset()
            return "game"
        if ui.button(self.surface, SCREEN_WIDTH // 2 - 100, "Main Menu", y_offset=120):
            return "menu"

        return None